package com.xindacloud.sms.adapter.service.sms.impl;

import com.clxcommunications.xms.ApiConnection;
import com.clxcommunications.xms.ClxApi;
import com.clxcommunications.xms.api.MtBatchTextSmsCreate;
import com.clxcommunications.xms.api.MtBatchTextSmsResult;
import com.clxcommunications.xms.api.ReportType;
import com.google.gson.Gson;
import com.xindacloud.sms.adapter.bo.SubmitMessageBO;
import com.xindacloud.sms.adapter.constant.CommonConstant;
import com.xindacloud.sms.adapter.entity.SmsSubmissionRecord;
import com.xindacloud.sms.adapter.entity.SmsUserAllowOperator;
import com.xindacloud.sms.adapter.exception.ServiceException;
import com.xindacloud.sms.adapter.service.business.ISmsSubmissionRecordService;
import com.xindacloud.sms.adapter.service.business.ISmsUserAllowOperatorService;
import com.xindacloud.sms.adapter.service.business.ISmsUserService;
import com.xindacloud.sms.adapter.service.factory.SinchClientFactory;
import com.xindacloud.sms.adapter.service.sms.ISubmitMessageService;
import com.xindacloud.sms.adapter.utils.MessageTypeHelp;
import com.xindacloud.sms.adapter.utils.StatusEum;
import com.xindacloud.sms.adapter.utils.UnionResultHelp;
import com.xindacloud.sms.adapter.vo.SubmitMessageResultVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.math.BigDecimal;
import java.net.URI;
import java.util.Arrays;
import java.util.Objects;

@Service("sinchSubmitMessageService")
@Slf4j
public class SinchSubmitMessageServiceImpl implements ISubmitMessageService<SubmitMessageBO, SubmitMessageResultVO> {


    @Autowired
    private ISmsUserAllowOperatorService smsUserAllowOperatorService;
    @Autowired
    private ISmsSubmissionRecordService smsSubmissionRecordService;
    @Autowired
    private ISmsUserService smsUserService;

    private final SinchClientFactory sinchClientFactory;

    @Autowired
    public SinchSubmitMessageServiceImpl(SinchClientFactory sinchClientFactory) {
        this.sinchClientFactory = sinchClientFactory;
    }


    @Override
    public SubmitMessageResultVO submitMessage(SubmitMessageBO submitMessageBO) {

        final String recipient = submitMessageBO.getRecipient();
        final String apiSecret = submitMessageBO.getApiSecret();
        final String apiUrl = submitMessageBO.getApiUrl();
        final String apiKey = submitMessageBO.getApiKey();
        final Integer userId = submitMessageBO.getUserId();
        final String taskId = submitMessageBO.getTaskId();
        final String senderId = submitMessageBO.getSenderId();
        final String messageBody = submitMessageBO.getMessageBody();
        final Integer messageCount = submitMessageBO.getMessageCount();
        final String callBackUrl = submitMessageBO.getCallBackUrl();
        final BigDecimal costPrice = submitMessageBO.getCostPrice();
        final String countryCode = submitMessageBO.getCountryCode();
        final String countryPrefix = submitMessageBO.getCountryPrefix();
        final String agentId = submitMessageBO.getAgentId();

        ApiConnection apiConnection = null;
        try {

            apiConnection = sinchClientFactory.getSinchClient(apiKey, apiSecret, apiUrl);
            MtBatchTextSmsCreate.Builder builder = ClxApi.batchTextSms().sender(senderId).body(messageBody);
            String[] splitRecipients = recipient.split(CommonConstant.SEPARATOR_STR);
            if (splitRecipients.length > 1) {
                builder.addAllRecipients(Arrays.asList(splitRecipients));
            } else {
                builder.addRecipient(recipient);
            }
            builder.deliveryReport(ReportType.FULL);
            builder.callbackUrl(new URI(callBackUrl));
            MtBatchTextSmsResult result = apiConnection.createBatch(builder.build());
            log.info("Sinch发送返回结果:{}", new Gson().toJson(result));
            //获取手机所属运营商名称
          /*  final String networkName = PhoneUtil.getCarrier(recipient.replaceAll(countryPrefix, ""), Integer.parseInt(countryPrefix));
            final String network = smsUserAllowOperatorService.queryNetworkCodeByNetworkName(userId, countryCode, countryPrefix, networkName);*/
            //根据返回的network查询当前号码所属国家的售价
            //SmsUserAllowOperator userAllowOperator = smsUserAllowOperatorService.queryOneMaxPriceOrderByDesc(userId, countryCode, countryPrefix, "");
            SmsUserAllowOperator userAllowOperator = smsUserAllowOperatorService.queryOneMaxPriceByAgentId(userId, countryCode, countryPrefix, agentId);
            /*if (StringUtils.isNotEmpty(network)) {
                userAllowOperator = smsUserAllowOperatorService.queryOneMaxPriceOrderByDesc(userId, countryCode, countryPrefix, network);
            } else {
                userAllowOperator = smsUserAllowOperatorService.queryOneMaxPriceOrderByDesc(userId, countryCode, countryPrefix, "");
            }
            if (Objects.isNull(userAllowOperator)) {
                throw new ServiceException("未同步运营商价格,或所以服务通道被禁用.", UnionResultHelp.StatusEnum.InnerError.code());
            }*/
            final BigDecimal calcMessagePrice = MessageTypeHelp.calcMessagePrice(userAllowOperator.getPrice(), messageCount);
            final String messageId = result.id().toString();
            final boolean messageIdNotEmpty = StringUtils.isNotEmpty(messageId);
            final SmsSubmissionRecord submissionRecord = SmsSubmissionRecord.builder()
                    .messageId(messageId)
                    .agentId(messageIdNotEmpty ? agentId : "")
                    .free(messageIdNotEmpty ? calcMessagePrice : BigDecimal.ZERO)
                    .costPrice(messageIdNotEmpty ? costPrice : BigDecimal.ZERO)
                    .countryCode(countryCode)
                    .prefix(countryPrefix)
                    .messageCount(messageCount)
                    .network(userAllowOperator.getNetworkCode())
                    .submitStatusCode(messageIdNotEmpty ? 0 : 400)
                    .finalStatus(messageIdNotEmpty ? StatusEum.SUBMITTED.desc : StatusEum.FAILED.desc)
                    .errorText(messageIdNotEmpty ? "" : "请求异常,请检查参数")
                    .sendTo(recipient)
                    .taskId(taskId)
                    .userId(userId)
                    .minus(true)
                    .build();
            smsSubmissionRecordService.updateSmsSubmissionRecordFor(submissionRecord);
            if (messageIdNotEmpty) {
                //更新用户账户
                smsUserService.updateSmsPrice(userId, calcMessagePrice);
            }
            return SubmitMessageResultVO.builder()
                    .errorText("")
                    .messageId(messageId)
                    .network("")
                    .submitStatus(0)
                    .build();
        } catch (Exception e) {
            log.error("Sinch发送短信异常:{}", e.getMessage(), e);
            throw new ServiceException("短信发送异常:".concat(e.getMessage()), UnionResultHelp.StatusEnum.BadRequest.code());
        } finally {
            try {
                if (Objects.nonNull(apiConnection)) {
                    apiConnection.close();
                }
            } catch (IOException e) {
                log.error("关闭Sinch连接异常:{}", e.getMessage(), e);
            }
        }
    }

}
